package day05;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator;
import org.springframework.context.support.GenericApplicationContext;

/**
 * @title: App64_2
 * @author: lbj
 * @date: 2022/5/2 8:42 上午
 * @description: TODO 类描述
 */


public class App64_1 {

    public static void main(String[] args) {
        final GenericApplicationContext context = new GenericApplicationContext();
        context.registerBean("aspect1",Aspect1.class);
        context.registerBean("aspect2",Aspect2.class);
        context.registerBean("aspect3",Aspect3.class);
        //自动代理后处理器
        context.registerBean(AnnotationAwareAspectJAutoProxyCreator.class);
        context.refresh();

        AnnotationAwareAspectJAutoProxyCreator creator = context.getBean(AnnotationAwareAspectJAutoProxyCreator.class);
        final Object o = creator.wrapIfNecessary(new Target1(), "target1", "target1");
        System.out.println(o.getClass());

//        context.registerBean("target1",Target1.class);
//        context.registerBean("target2",Target2.class);
//        context.refresh();
//
//        final Target1 target1 = context.getBean(Target1.class);
//        final Target2 target2 = context.getBean(Target2.class);
//
//        target1.foo();
//        System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
//        target2.bar();
    }

    static class Target1{
        public void foo() {
            System.out.println("target1 foo");
        }
    }

    static class Target2{
        public void bar() {
            System.out.println("target2 bar");
        }
    }

    static class Target3{
        public void baz() {
            System.out.println("target3 bz");
        }
    }

    @Aspect
    static class Aspect1 {
        @Around("execution(* foo())")  //切面
        public Object around(ProceedingJoinPoint pjp) throws Throwable {
            System.out.println("Aspect1 around");
            return pjp.proceed();
        }
    }

    @Aspect
    static class Aspect2 {
        @Before("execution(* foo())")
        public void before(){
            System.out.println("Aspect2 before");
        }

        @After("execution(* foo())")
        public void after(){
            System.out.println("Aspect2 after");
        }
    }

    @Aspect
    static class Aspect3 {
        @Before("execution(* bar())")
        public void before(){
            System.out.println("Aspect3 before");
        }
    }

}
